home *** CD-ROM | disk | FTP | other *** search
- // CPROG19.CPP - an OOP version of last month's CPROG15.CPP
- // It creates and uses a file directory object
-
-
- #include <stdlib.h>
- #include <iostream.h> // Needed for stream-related features such as cout and <<
- #include <iomanip.h> // Defines manipulators for cout - such as setw() to set the field width
- #include <dos.h>
- #include <dir.h>
- #include <string.h>
-
-
-
- //////////////////////////////////////////////////////////////////////////////
- class dirlist { // Object to create, store and provide access to linked list
- // of filenames.
-
- struct filerecord { // Now private data within
- char filename[13]; // the dirlist object. Only
- char attribute; // member functions can get
- struct filerecord *previous; // at the pointers *firstrec
- struct filerecord *next; // and *current, and therefore
- } *firstrec, *current; // any structures they point to
-
- void makeattstring(char attribute); // A member function to turn
- // an attribute into a string.
- // It is private, so only
- // other member functions may
- // use it.
- public:
- dirlist(char *pathname); // Constructor builds the list
- ~dirlist(void); // Destructor destroys list
-
- void setrec(int recnum); // Sets the number of the
- // record we're interested in
- char filename[13], attstring[7]; // Character arrays to be
- // filled in with data from
- // current record by setrec()
- };
- //----------------------------------------------------------------------------
- dirlist::dirlist(char *pathname) // The constructor builds the list
- { // The code is pasted from CPROG15.CPP with
- // a couple of minor mods such as the list
- // and its pointers being part of the object
- // and the comments removed
- struct ffblk filedetails;
- struct filerecord *temp;
-
- findfirst(pathname, &filedetails, FA_RDONLY+FA_HIDDEN+FA_SYSTEM+FA_LABEL+FA_DIREC+FA_ARCH);
- temp=firstrec=0;
- do {
- if( ! (current=new filerecord) )
- {
- cout << "Oh dear, we're clean out of spare bytes!\n";
- exit(0);
- }
-
- if( firstrec == 0 )
- firstrec=current;
- strcpy( current->filename, filedetails.ff_name );
- current->attribute = filedetails.ff_attrib;
- current->previous=temp;
- if ( temp )
- temp->next=current;
- temp=current;
- } while( ! findnext(&filedetails) );
- current->next=0;
-
- setrec(0); // Make sure the public variables are intialised
- }
-
- //----------------------------------------------------------------------------
- dirlist::~dirlist(void) // Destructor releases all the memory allocated
- // to the linked list by the constructor using
- // DELETE. It threads forward along the NEXT pointers
- // deleting the previous strucutre in list.
- {
- current=firstrec;
- do {
- current=current->next;
- delete current->previous;
- } while( current->next );
- delete current; // At end of list delete current (=final) structure.
- }
- //----------------------------------------------------------------------------
- void dirlist::setrec(int recnum) // Makes current record recnum-th in list
- // and copies details to public char
- // arrays attstring[] and filename[]
- // Index for recnum begins at 0
- // This is a very slow method - in a
- // live program a faster technique would
- // be used.
- {
- for(current=firstrec; current->next && recnum; recnum--)
- current=current->next; // Step forward as long as there's
- // a structure to step forward to
- // and recnum hasn't been decremented
- // to zero.
-
- if( recnum ) // If recnum was bigger than the list, and therefore
- // hasn't been decremented to zero...
- attstring[0]=filename[0]='\0'; // Signify error by zeroing
- // filename and attribute
- else
- {
- makeattstring(current->attribute); // else update them with
- strcpy(filename, current->filename); // details from current
- } // record
- }
- //----------------------------------------------------------------------------
- void dirlist::makeattstring(char attribute) // Converts attribute byte
- { // to a user-friendly string
- static char attlets[]= "ADLSHR"; // - another paste from
- int i; // CPROG15.CPP, with comments
- // removed and attstring[]
- for(i=5; i>=0; i--) // placed in object's public
- { // data area.
- attstring[i]= (attribute & 1 ) ? attlets[i] : '-';
- attribute=attribute >> 1;
- }
- attstring[6]='\0';
- }
- //////////////////////////////////////////////////////////////////////////////
- void main(void)
- {
- int i;
- dirlist dir1("C:\\*.*"); // Create a dirlist object called dir1. Its
- // constructor function expects a pathname
- // for the directory to be read.
- /* Print out the directory names. Knows when it has got to end of list
- when the filename becomes a null string (ie '\0' at 1st char position */
- for(i=0, dir1.setrec(0); dir1.filename[0]; i++ )
- {
- dir1.setrec(i); // Set record to current value of i
- cout << setw(12) << dir1.filename << '\t' << dir1.attstring << '\n';
- }
- }
-
- //////////////////////////////////////////////////////////////////////////////
- /* NOTES:
- 1: setw() is what is known as a manipulator. It is one of a series of
- functions which manipulate the format of data on its way to the output
- stream (cout) or coming from the input stream (cin). setw(12) is equivalent
- to %12s in a printf() call. The cout line is equivalent to:
- printf("%12s\t%s\n", dir1.filename, dir1.attstring);
- Manipulators are not well covered in the help system. Read the file iomanip.h
- for more information, though this is one area where you really need
- a manual.
- 2: Improvments to the dirlist class would be...
- - to get it to store the pathanme so that if multiple instamces are created
- for different directories, it is easy to see what's what.
- - a faster record location algorithm for setrec(). Two ideas for this are:
- - not to use a linked list but an array of structures. This would require
- the number of filenames to be determined first, then a block of
- memory large enough for an array to be allocated before reading the
- names
- - to build a list of pointers to every 16th record, and use the nearest
- index as a startign point for threading
- - functions to step backwards or forwards n records from the current position
- - a fucntion to sort records according to one of a number of criteria, like
- the sort options in File Manager.
- - the ability to filter out certain types of file by feeding the constructor
- allowable file attributes.
- */